package it.Impianti.Gruppo12;

import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;


public class Sieve {
	
	private static Boolean[] isPrime;
	private final static int nMax=4;
	private static int indice; //Scorre tutto l'array
	private static int indiceK; //Scorre gli elementi multipli di indice
	private static int iterazioni=1000;
	private static int numeriPrimi;
	private static ArrayList<Long> arrayTempi; 
	private static int numeroMassimo=10;
	private static FileWriter fileWriter;
	
	public static void main(String[] args) {
		long tempoInizio;
		long tempoFine;
		try {
			fileWriter = new FileWriter("SieveTempiJava.csv");
			fileWriter.append("Iterazioni,IterazioneAttuale,Numero Elementi,Tempo Esecuzione\n");

		} catch (IOException e) {
			e.printStackTrace();
		}
		
		arrayTempi = new ArrayList<Long>();
		

		for (int t = 0; t < iterazioni; t++){
			numeroMassimo = 10;
			
			/*
			 * Ciclo sul numero di iterazione perch� la misura sia effettuata sulla media e
			 * non sul singolo valore
			 */
			 for (int i = 0; i < nMax; i++){
				numeroMassimo = numeroMassimo*10; 
				tempoInizio=0;
				tempoFine=0;
				tempoInizio=System.nanoTime();
				int numeriPrimi = sieveAlghoritm(numeroMassimo);
				tempoFine=System.nanoTime();
				System.out.println("I numeri primi minori di "+numeroMassimo+" sono: "+numeriPrimi);
				arrayTempi.add( (long) (tempoFine - tempoInizio) );
				try {
					fileWriter.append(iterazioni+","+
									  String.valueOf(t)+","
									  +numeroMassimo+","
									  +String.valueOf( (long) (tempoFine - tempoInizio) )+"\n");
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		}
		try {
			fileWriter.flush();
			fileWriter.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		ArrayList<Long> medieCalcolate = calcolaMedie(arrayTempi);
		
		for(int k=0; k<medieCalcolate.size(); k++){
			System.out.println("La media dei tempi calcolata e': "+medieCalcolate.get(k));				
		}
		
	}
	
	public static int sieveAlghoritm(int numeroMassimo){	
			
			isPrime=new Boolean[numeroMassimo+1];
			
			//Inizializzo tutti gli elementi dell'array al valore true
			for (int j = 1; j <= numeroMassimo; j++){
				isPrime[j] = true;
			}
			
			indice=2;
			
			//I numeri primi di un numero N sono compresi tra 1 e SQRT(N)
			while ((indice*indice) <= numeroMassimo){
				
				if (isPrime[indice]){
				 
					indiceK = indice + indice;
					
					while (indiceK <= numeroMassimo){
						isPrime[indiceK] = false;
						indiceK = indiceK + indice;
					}
					
				}
			
				indice++;
			}
			
			numeriPrimi=0;
			for(int i = 1; i <= numeroMassimo; i++){
				if(isPrime[i]){
					numeriPrimi++;
				}
			}		
			
			return numeriPrimi;
			

			
		}		
		
		
		private static ArrayList<Long> calcolaMedie(ArrayList<Long> tempi){
			ArrayList<Long> medie = new ArrayList<Long>();
			long somma = 0;
			for(int k=0; k < nMax; k++){
				for(int j=0; j < iterazioni; j++){
					somma = somma + tempi.get(k+((nMax)*j));
				}
				medie.add(somma/iterazioni);
				somma=0;
			}
			
			return medie;
		}
	

}
